package cn.lingyangwl.framework.core.response.wrap;

import cn.lingyangwl.framework.core.response.Resp;
import cn.lingyangwl.framework.core.utils.servlet.ServletUtils;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;

import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 包装返回结果
 *
 * @author shenguangyang
 */
public class WebWrapReturnValueHandler implements HandlerMethodReturnValueHandler {
    private final RequestResponseBodyMethodProcessor target;

    public WebWrapReturnValueHandler(RequestResponseBodyMethodProcessor target) {
        this.target = target;
    }

    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        return true;
    }

    @Override
    public void handleReturnValue(Object returnValue, MethodParameter methodParameter,
                                  ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest) throws Exception {
        Executable executable = methodParameter.getExecutable();

        Method method = (Method) executable;
        Class<?> returnType = method.getReturnType();
        if (returnType.equals(Resp.class)) {
            Resp<?> resp = (Resp<?>) returnValue;
            HttpServletResponse response = ServletUtils.getResponse();
            if (Objects.nonNull(response)) {
                response.setStatus(resp.getStatus().value());
            }
            target.handleReturnValue(resp.wrapOfServlet(), methodParameter, modelAndViewContainer, nativeWebRequest);
        } else {
            target.handleReturnValue(returnValue, methodParameter, modelAndViewContainer, nativeWebRequest);
        }
    }
}
